//***************************************************************************//
//* 版权所有  www.sh-easy.com
//*
//* 内容摘要：客户端服务器共用的TCP连接相关，包括内部重连处理等
//*	
//* 当前版本：V1.0		
//* 作    者：zhfayuan
//* 完成日期：2015-12-26
//**************************************************************************//
#ifndef CLIENTCOMMON_H
#define CLIENTCOMMON_H
#include "SDThread.h"
#include "SDMutex.h"
#include "SDMessage.h"
#include "SDEventGroup.h"
#include "SDSocket.h"


class CSDSingleComSocket : public CSDSocket
{
public:
	CSDSingleComSocket(const char *strName, BYTE byType = TCP_SOCKET_COMMON_CLIENT);
	virtual ~CSDSingleComSocket();

public:
	//连接服务器并与其完成信令握手
#if 0
	BOOL connect(UINT unUserId, char *strIp, int nPortId, int nPingPort, int nTimeout = 0, 
						Interrupt_Callback interrupt_callback = NULL, void* opaque_callback = NULL,
						//以下参数为媒体服务器连接域服务器时所需，客户端忽略
						UINT unIPFirst=0, UINT unIPNetTypeFirst=0, UINT unIPSecond=0, UINT unIPNetTypeSecond=0, 
						UINT unServerId=0, UINT unServerType=0);
#endif

	BOOL connect( char *strIp, int nPortId, int nPingPort, int nTimeout = 0, 
						Interrupt_Callback interrupt_callback = NULL, void* opaque_callback = NULL,
						//以下参数为媒体服务器连接域服务器时所需，客户端忽略
						UINT unIPFirst=0, UINT unIPNetTypeFirst=0, UINT unIPSecond=0, UINT unIPNetTypeSecond=0, 
						UINT unServerId=0, UINT unServerType=0);

	virtual BOOL CreateTcpResource(int nsock, UINT unIp, ConnectInitMsg *pMsg);
	virtual BOOL ReinitTcpResource(int nsock, UINT unIp, ConnectInitMsg *pMsg);

    virtual void SetClientId(UINT64 unClientId);

	virtual void Close();

	virtual void ProcessReciveData(int nLen, BYTE *byBuf);

	virtual void Error(int nErrorId);

	virtual BOOL sdsend(PACK_MESSAGE* pack);

	UINT   GetLocalIpAdrress();
	UINT   GetRemoteIpAddress() { return m_unRemoteIp; }

	int    GetObjectIndex() { return m_nIndex; }

	BOOL IsWork()
	{
		return !m_bClosed && m_ReceThrd.isRun();
	}

	BOOL SetKeepAlive(UINT unInterval, UINT unTime);
	void DisableReconnect() {m_bDisableReconnect = TRUE;}
    
    virtual void Command(PACK_MESSAGE *pack){}
    virtual BOOL RespondPackMessage(PACK_MESSAGE *pack){return TRUE;}

private:
	BOOL sdsend(int nLen, char *buf);
	BOOL sdrecive(int &nLen, char *&buf);
protected:
	BYTE               m_bClosed;   // 是否为关闭状态
    PACK_MESSAGE       *m_CryptoPack;
private:
	BYTE               m_byType;           // 通道连接的类型，TCP_SOCKET_COMMON_SERVER表示为服务器端的连接类型，
										   // TCP_SOCKET_COMMON_CLIENT表示客户端连接类型,此值由其子类的构造函数中赋值	
	int                m_nConnectPort;     // 连接端口
	int				   m_nPingPort;	       // 重连使用的ping端口	
	BYTE               m_byReciveStatus;   // 接受数据线程是否工作正常
	int                m_sockfd;
	UINT               m_unRemoteIp;
	UINT               m_unLocalIp; 

	int                m_nIndex; //用于服务器上唯一标识Client对象，而UID则存在同一个账号同时登陆的情况

	CSDThread	       m_ReceThrd;
	void               *m_cssend;
	CSDEvent           m_evtReconnect;
	BOOL			   m_bQuitRecvThread;
	BOOL               m_bDisableReconnect;
	//UINT			   m_unUserId; //客户端本地看到的自身ID， 用于日志
	UINT64			   m_unClientUserId; //服务器看到的客户端ID，用于日志
private:
	static   int TcpRecvThreadProc(void* pParam);
	static   int TcpRecvThreadClose(void* pParam);
	//通过自定义的TCP握手信令判断服务器是否还存在
	BOOL mfIsServerExist(char *strIp, int nPortId);
	static   int IsCloseRequest(void* pParam);

	static char		m_strPrtTag[];
};


#endif // !defined(CLIENTCOMMON_H)
